package com.tanglon.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanglon.domain.entity.User;
import com.tanglon.domain.vo.ExcelUserVo;
import com.tanglon.mapper.UserMapper;
import com.tanglon.service.ExcelWriteService;
import com.tanglon.service.UserService;
import com.tanglon.utils.BeanCopyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


@Service
@Slf4j
public class ExcelWriteServiceImpl implements ExcelWriteService {

    @Resource
    private UserService userService;

    @Resource
    private UserMapper userMapper;

    @Override
    public void exportData(HttpServletResponse response) {
        long start1 = System.currentTimeMillis();

        //每次查询1万条
        Integer pageSize =10000;

        //线程池大小，
        Integer poolSize =10;

        //导出的文件名
        String fileName=String.valueOf(UUID.randomUUID());
        //查询数据总数
        Integer totalCount = userMapper.selectCount(null);

        if(totalCount==0){
            System.out.println("没有数据需要导出");
            return;
        }
        int loopCount = (int) Math.ceil((double) totalCount/pageSize);

        //设置shuju
        final CountDownLatch countDownLatch = new CountDownLatch(loopCount);
        System.out.println("要查询的次数："+countDownLatch);
        ExecutorService executorService= Executors.newFixedThreadPool(poolSize);
        OutputStream outputStream = null;

        try{
            outputStream=response.getOutputStream();

            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            for (int i = 0; i < loopCount; i++) {
                final int pageNum = i + 1;
                //线程池
                executorService.execute(() ->{
                    //开始时间
                    long start=System.currentTimeMillis();

                    Page<User> page = userMapper.selectPage(new Page(pageNum, pageSize), null);
                    List<ExcelUserVo> list= BeanCopyUtils.copyBeanList(page.getRecords(),ExcelUserVo.class);

                    log.info("第{}页，查询耗时===》{}",pageNum,System.currentTimeMillis()-start);
                    long start2 = System.currentTimeMillis();

                    WriteSheet writeSheet = EasyExcel.writerSheet(pageNum, "第"+pageNum+"页")
                            .head(ExcelUserVo.class)
                            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                            .build();

                    synchronized (userMapper) {
                        excelWriter.write(list, writeSheet);
                        log.info("数据写出耗时===》 {}",System.currentTimeMillis()-start2);
                    }
                    
                    countDownLatch.countDown();
                });
            }

            countDownLatch.await();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            excelWriter.finish();
            outputStream.flush();
            executorService.shutdown();//关闭线程池
            outputStream.close();
            log.info("总耗时====》{}",System.currentTimeMillis()-start1);

        } catch (IOException |InterruptedException   e) {
            throw new RuntimeException(e);
        }

    }
}
